#include "JFile.h"
#include "JSerialize.h"
#include <fstream>
#include "JLog.h"
#include <boost/filesystem.hpp>
#include "JFileException.h"
#include "JRepositoryConfig.h"
#include "JDefine.h"
#include "JRepository.h"

using namespace boost::filesystem;

void JFile::CreateFile(std::string fileName) 
{
    std::fstream fs(fileName.c_str(), std::fstream::out | std::fstream::trunc | std::fstream::binary);
    if (!fs)
    {
        throw JFileException("Function:JFile::CreateFile error.");
    }
    else 
    {
        fs.close();
    }
}

JFile::JFile( std::string _fileName ):JBaseFile(_fileName)
{

}

JFile::JFile(JBaseFile& _baseFile) : JBaseFile(_baseFile)
{
    
}

std::fstream& JFile::OpenStream(std::ios_base::openmode _Mode,std::string _fileName) 
{
    if(_fileName == "")
    {
        _fileName = this->filename;
    }
    const char* c = _fileName.c_str();
    fs.open(c, _Mode);
    if (fs) 
    {
        return fs;
    } 
    else 
    {
        throw JFileException("Function::OpenStream error.");
    }
}

void JFile::CloseStream()
{
	if(fs)
	{
            fs.close();
	}
}

bool JFile::IsExist( std::string fullFileName )
{
	path p(fullFileName);
	if(exists(p))
	{
		return true;
	}
	return false;
}

JFile::~JFile( void )
{

}

int JFile::Serialize( JInOutPut& _strea,int& allSize) 
{
    ////Serialize begin.
    //std::fstream strea;
    ////Serialize end.
    int classSize = 0, selfSize = 0;
    JSerialize::SerializeHead(_strea, selfSize, classSize);
    JBaseFile::Serialize(_strea, classSize);
    JSerialize::Serialize(_strea, this->OpenStream(std::ios::in | std::ios::binary), classSize);
    return JSerialize::SerializeTail(_strea, allSize, selfSize, classSize);
}

int JFile::ReSerialize( JInOutPut& _strea) 
{
    this->OpenStream(std::ios::out | std::ios::binary | std::ios::trunc);
    int classSize = JSerialize::ReSerializeHead(_strea);
    JBaseFile::ReSerialize(_strea);
    JSerialize::ReSerializeFstream(_strea, this->fs);
    this->CloseStream();
    return classSize;
}

int JFile::FileSize( std::string _fullFileName )
{
    return file_size(_fullFileName);
}

JFile::JFile()
{
    
}

JFile::JFile(const JFile& _file)
{
    this->createTime = _file.createTime;
    this->filename = _file.filename;
    this->tempFileName = _file.tempFileName;
    this->verifyTime = _file.verifyTime;
}

void JFile::SaveToFileName(JInOutPut& _strea,std::string _fullFileName)
{
    JFile file(_fullFileName);
    file.OpenStream(std::ios::out | std::ios::binary | std::ios::trunc);
    JSerialize::ReSerializeFstream(_strea,file.fs);
    file.CloseStream();
}

void JFile::SaveToFileName(std::string _fullFileName)
{
    JFile::CopyBaseFile(filename,_fullFileName);
}

/*到远程服务器，建包*/
int JFile::PackStubMessage(JInOutPut& _strea, int& _allSize) 
{
    int classSize = 0, selfSize = 0;
    JSerialize::SerializeHead(_strea, selfSize, classSize);
    JBaseFile::PackStubMessage(_strea, classSize);
    JSerialize::Serialize(_strea, this->OpenStream(std::ios::in | std::ios::binary), classSize);
    return JSerialize::SerializeTail(_strea, _allSize, selfSize, classSize);
}

/*服务器解包*/
int JFile::UnPackStubMessage(JInOutPut& _strea) 
{
    //这里需要把文件先写到一个临时地址
    //this->tempFileName = JRepositoryConfig::repositoryRootPath + PATH_SPLIT + "tmp" + PATH_SPLIT + "tmp";
    this->tempFileName = JRepositoryConfig::repositoryTempFileFileName;
    this->OpenStream(std::ios::out | std::ios::binary | std::ios::trunc,tempFileName);
    int classSize = JSerialize::ReSerializeHead(_strea);
    JBaseFile::UnPackStubMessage(_strea);
    JSerialize::ReSerializeFstream(_strea, this->fs);
    this->CloseStream();
    return classSize;
}

void JFile::WriteToFile(char* c, int size)
{
    fs.write(c,size);
}